﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections.Generic;
using Microsoft.SharePoint.Utilities;
using SharePointListSecurity.Model;
using SharePointListSecurity.WebControls;
using System.Linq;
using SharePointListSecurity.Data;
using Data = SharePointListSecurity.Data;

namespace SharePointListSecurity.Layouts.SharePointListSecurity
{
    public partial class ListColumnPermissions : LayoutsPageBase
    {
        protected SPList spList;
        protected List<FieldPermissionInfo> fieldsPermissions;
        protected SPListSecurityContextDataContext context;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.HttpMethod == "POST")
                SPUtility.ValidateFormDigest();

            SPUser user = this.Web.CurrentUser;
            bool hasFullControl=  SPContext.Current.Web.AllRolesForCurrentUser.Contains(SPContext.Current.Web.RoleDefinitions["Full Control"]);
            if (hasFullControl)
            {
                context = new SPListSecurityContextDataContext(this.Web.Site.Url);

                string[] strLists = Request.QueryString.GetValues("List");
                if (strLists == null || strLists.Length < 1)
                {
                    throw new SPException(SPResource.GetString(Strings.MissingRequiredQueryString, "List"));
                }
                spList = this.Web.Lists.GetList(new Guid(strLists[0]), true);

                PopulateFieldTypes();
            }
            else
            {
                Response.Redirect(this.Web.Url + "/_layouts/accessdenied.aspx");
            }
        }

        private void PopulateFieldTypes()
        {
            int capacity = this.spList.Fields.Count;

            this.fieldsPermissions = new List<FieldPermissionInfo>(capacity);
            SPField field;

            for (int i = 0; i < capacity; i++)
            {
                field = this.spList.Fields[i];
                if (field.Hidden ||
                    !field.Reorderable)
                {
                    continue;
                }

                fieldsPermissions.Add(new FieldPermissionInfo()
                                          {
                                              Field = field,
                                              DisplayFormPermissions = GetDisplayFormPemissions(field, spList),
                                              AddFormPermissions = GetAddFormPemissions(field, spList),
                                              EditFormPermissions = GetEditFormPemissions(field, spList)
                                          });
            }
        }

        private DisplayFormFieldsPermissions GetDisplayFormPemissions(SPField field, SPList list)
        {
            return context.DisplayFormFieldsPermissions
                          .FirstOrDefault(p => new Guid(p.ListID) == list.ID
                                               && new Guid(p.ColumnID) == field.Id);
        }
        private AddFormFieldsPermissions GetAddFormPemissions(SPField field, SPList list)
        {
            return context.AddFormFieldsPermissions
                          .FirstOrDefault(p => new Guid(p.ListID) == list.ID
                                               && new Guid(p.ColumnID) == field.Id);
        }
        private EditFormFieldsPermissions GetEditFormPemissions(SPField field, SPList list)
        {
            return context.EditFormFieldsPermissions
                          .FirstOrDefault(p => new Guid(p.ListID) == list.ID
                                               && new Guid(p.ColumnID) == field.Id);
        }

        protected void RenderDisplayUsers(DisplayFormFieldsPermissions permissions)
        {
            var html = "";
            if (permissions != null)
            {
                if (permissions.UsersAndGroups.Count > 0)
                {
                    html = "<span class=\"userListContainer\">" + String.Join("<br />", new List<string>(permissions.UsersAndGroups).ToArray()) +"</span>";
                }
                else
                    html = "Everyone";
            }
            Response.Write(html);
        }

        protected void RenderDisplayPermissionFlag(DisplayFormFieldsPermissions permissions)
        {
            var html = "<span  class=\"flag notSet\"> Not Set</span>";
            if (permissions != null)
            {
                if ((permissions.Permission == PermissionType.ShowField && permissions.UsersAndGroups.Count > 0)
                    || (permissions.Permission == PermissionType.HideField && permissions.UsersAndGroups.Count == 0))
                {
                    html = "<span class=\"flag allow\"> Allow</span>";
                }
                else
                    html = "<span class=\"flag deny\"> Deny</span>";
            }
            Response.Write(html);
        }

        protected void RenderEditUsers(EditFormFieldsPermissions permissions)
        {
            if (permissions != null && !string.IsNullOrEmpty(permissions.Permission))
            {
                var html = "";

                if (permissions.UsersAndGroups.Count > 0)
                    html = "<span class=\"userListContainer\">" + String.Join("<br />", new List<string>(permissions.UsersAndGroups).ToArray()) + "</span>";
                else
                    html = "Everyone";

                Response.Write(html);
            }
        }

        protected void RenderEditPermissionFlag(EditFormFieldsPermissions permissions)
        {
            if (permissions != null && !string.IsNullOrEmpty(permissions.Permission))
            {
                var html = "";

                if ((permissions.Permission == PermissionType.ShowField && permissions.UsersAndGroups.Count > 0) 
                    || (permissions.Permission == PermissionType.HideField && permissions.UsersAndGroups.Count == 0))
                    html = "<span class=\"flag allow\"> Allow</span>";
                else
                    html = "<span class=\"flag deny\"> Deny</span>";

                Response.Write(html);
            }
        }

        protected void RenderEditDisplayModeUsers(EditFormFieldsPermissions permissions)
        {
            if (permissions != null && !string.IsNullOrEmpty(permissions.DisplayMode))
            {
                var html = "";

                if (permissions.DisplayModeUsersAndGroups.Count > 0)
                    html = "<span class=\"userListContainer\">" + String.Join("<br />", new List<string>(permissions.DisplayModeUsersAndGroups).ToArray()) + "</span>";
                else
                    html = "Everyone";

                Response.Write(html);
            }
        }

        protected void RenderEditDisplayModeFlag(EditFormFieldsPermissions permissions)
        {
            if (permissions != null && !string.IsNullOrEmpty(permissions.DisplayMode))
            {
                var html = "";

                if ((permissions.DisplayMode == PermissionType.Editable && permissions.DisplayModeUsersAndGroups.Count > 0)
                    || (permissions.DisplayMode == PermissionType.ReadOnly && permissions.DisplayModeUsersAndGroups.Count == 0))
                    html = "<span class=\"flag editable\"> Editable</span>";
                else
                    html = "<span class=\"flag readOnly\"> ReadOnly</span>";

                Response.Write(html);
            }
        }

        protected void RenderAddUsers(AddFormFieldsPermissions permissions)
        {
            var html = "";
            if (permissions != null)
            {
                if (permissions.UsersAndGroups.Count > 0)
                {
                    html = "<span class=\"userListContainer\">" + String.Join("<br />", new List<string>(permissions.UsersAndGroups).ToArray()) + "</span>";
                }
                else
                    html = "Everyone";
            }
            Response.Write(html);
        }

        protected void RenderAddPermissionFlag(AddFormFieldsPermissions permissions)
        {
            var html = "<span  class=\"flag notSet\"> Not Set</span>";
            if (permissions != null)
            {
                if ((permissions.Permission == PermissionType.ShowField && permissions.UsersAndGroups.Count > 0)
                    || (permissions.Permission == PermissionType.HideField && permissions.UsersAndGroups.Count == 0))
                {
                    html = "<span class=\"flag allow\"> Allow</span>";
                }
                else
                    html = "<span class=\"flag deny\"> Deny</span>";
            }
            Response.Write(html);
        }

        protected void DeltePermissions_Click(object sender, EventArgs e)
        {
            var displayPermissions = context.DisplayFormFieldsPermissions
                                            .Where(p => new Guid(p.ListID) == spList.ID);
            if (displayPermissions != null)
                context.DisplayFormFieldsPermissions.DeleteAllOnSubmit(displayPermissions);

            var editPermissions = context.EditFormFieldsPermissions
                                         .Where(p => new Guid(p.ListID) == spList.ID);
            if (editPermissions != null)
                context.EditFormFieldsPermissions.DeleteAllOnSubmit(editPermissions);

            var addPermissions = context.AddFormFieldsPermissions
                                        .Where(p => new Guid(p.ListID) == spList.ID);
            if (addPermissions != null)
                context.AddFormFieldsPermissions.DeleteAllOnSubmit(addPermissions);

            context.SubmitChanges();
            Response.Redirect(this.Web.Url + String.Format("/_layouts/sharePointlistSecurity/listcolumnpermissions.aspx?List={0}", spList.ID.ToString()));
        }
    }
}
